package cache

import (
	"bytes"
	"encoding/json"
	"fmt"
	"time"
)

// ----------------------------------------
//  Redis JSON 数据
// ----------------------------------------
type RedisJSON struct {
	client *RedisClient
	key    string
}

func CreateRedisJSON(client *RedisClient, key string, args ...interface{}) *RedisJSON {
	if len(args) > 0 {
		key = fmt.Sprintf(key, args...)
	}

	return &RedisJSON{client: client, key: key}
}

func (j *RedisJSON) Key() string {
	return j.key
}

func (j *RedisJSON) Exists() (bool, error) {
	count, err := j.client.Exists(j.key).Result()
	return count == 1, err
}

func (j *RedisJSON) Get(v interface{}) error {
	if bs, err := j.client.Get(j.key).Bytes(); err != nil {
		return err
	} else {
		return json.Unmarshal(bs, v)
	}
}

func (j *RedisJSON) Set(v interface{}, expiration time.Duration) error {
	if bs, err := json.Marshal(v); err != nil {
		return err
	} else {
		return j.client.Set(j.key, bytes.NewBuffer(bs).String(), expiration).Err()
	}
}

func (j *RedisJSON) SetNX(v interface{}, expiration time.Duration) error {
	if bs, err := json.Marshal(v); err != nil {
		return err
	} else {
		return j.client.SetNX(j.key, bytes.NewBuffer(bs).String(), expiration).Err()
	}
}

func (j *RedisJSON) TrySetNX(v interface{}, expiration time.Duration) (bool, error) {
	if bs, err := json.Marshal(v); err != nil {
		return false, err
	} else {
		return j.client.SetNX(j.key, bytes.NewBuffer(bs).String(), expiration).Result()
	}
}

func (j *RedisJSON) SetXX(v interface{}, expiration time.Duration) error {
	if bs, err := json.Marshal(v); err != nil {
		return err
	} else {
		return j.client.SetXX(j.key, bytes.NewBuffer(bs).String(), expiration).Err()
	}
}

func (j *RedisJSON) TrySetXX(v interface{}, expiration time.Duration) (bool, error) {
	if bs, err := json.Marshal(v); err != nil {
		return false, err
	} else {
		return j.client.SetXX(j.key, bytes.NewBuffer(bs).String(), expiration).Result()
	}
}

func (h *RedisJSON) Destroy() error {
	return h.client.Del(h.key).Err()
}
